var PAGE_LIMIT=15;

if (typeof Object.beget !== 'function') {
	Object.beget=function(o) {
		var F=function() {};
		F.prototype=o;
		return new F();
	};
}

JSER={};

JSER.data={};

JSER.Record=function(config) {
	
	var scope=this;
	
	this.config=config;
	
	this.name=this.config.name;
	this.title=this.config.title;
	this.controller=this.config.controller;
	
	this.getItems=function() {
		var list=[];
		var obj=null;
		
		for (var i=0; i<config.items.length; i++) {
			obj=new Object();
			
			obj.name=config.items[i].name;
			obj.type=config.items[i].type;
			
			list.push(obj);
		}	
		
		return list;
	};
	
	this.obj=Ext.data.Record.create(scope.getItems());
	
	this.get=function() {
		return this.obj;
	};
};

JSER.Store=function(config) {
	
	this.config=config;
	
	this.getName=function() {
		if (this.config.name==undefined)
			throw ("Propriedade obrigatória não definida: name.");
		this.name=this.config.name;
		return this.name;
	};
	
	this.getId=function() {
		return this.getName()+'-store';
	};
	
	this.getRestful=function() {
		return (this.config.restful)? this.config.restful : true;
	};
	
	this.getController=function() {
		return (this.config.controller)?
			this.config.controller
			:
			this.config.name+'s';
	};
	
	this.getEntity=function() {
		if (!this.entity) 			
			this.entity=this.config.entity.get();
				
		return this.entity;
	};
	
	this.getReaderFields=function() {
		return (this.config.readerFields)? 
			this.config.readerFields
			:
			this.getEntity().prototype.fields.keys;
	};
	
	this.getProxy=function() {
		return new Ext.data.HttpProxy({
	    	url: this.getController()
	    });
	};
	
	this.getReader=function() {
		return new Ext.data.JsonReader({
	        root: 'data',
	        totalProperty: 'total',
	        idProperty: 'id',
	        fields: this.getReaderFields()
	    }, this.getEntity());
	};
	
	this.getWriter=function() {
		return new Ext.data.JsonWriter({
			encode: false,
			writeAllFields: true
		});
	};	
	
	this.obj=new Ext.data.Store({
		id				: this.getId(),
		name			: this.getName(),
		baseParams		: {'start': 0, 'limit': PAGE_LIMIT},
		successProperty	: 'success',
		prettyUrls		: true,
		autoSave		: false,
		autoLoad		: false,
		batch			: false,
		remoteSort		: true,
		restful			: this.getRestful(),
		
		proxy			: this.getProxy(),		
		reader			: this.getReader(),		
		writer			: this.getWriter(),
	});		
	
	this.get=function() {
		return this.obj;
	};
};

JSER.Panel=function(container, config) {
	
	var that=this;
	
	this.container=container;
	this.config=config;
	
	this.getName=function() {
		if (!this.name)
			this.name=(this.config.name)? this.config.name : this.container.name+'-panel';
		
		return this.name;
	};
	
	this.getId=function() {
		if (!this.id)
			this.id=this.getName();
		return this.id;
	};	
	
	this.getItems=function() {
		if (!this.items)
			this.items=(this.config.items)? JSER.ItemsParse(this, this.config.items) : [];
		
		return this.items;
	};
	
	this.getTbar=function() {
		return {
			xtype: 'toolbar',
	        items: [
	            {
	                xtype: 'buttongroup',
	                title: '',
	                columns: 5,
	                frame: false,
	                border: false,
	                items: [
	                    {
	                        xtype	: 'button',
	                        id		: this.getId()+'-button-save',
	                        text	: 'Salvar',
	                        width	: 60,
	                        iconCls	: 'save',
	                        handler	: function() {
	                        	that.getForm().saveRecord();
					        }
	                    },
	                    {
	                        xtype	: 'button',
	                        id		: this.getId()+'-button-new',
	                        text	: 'Novo',
	                        width	: 60,
	                        disabled: true,
	                        iconCls	: 'add',
	                        handler	: function()	{
	                        	that.state().create().ready();
				        	}
	                    },
	                    {
	                        xtype	: 'button',
	                        id		: this.getId()+'-button-delete',
	                        text	: 'Deletar',
	                        width	: 60,
	                        disabled: true,
	                        iconCls	: 'remove',
	                        handler	: function() {  
	                        	that.getForm().deleteRecord();
	                    	}
	                    }
	                ]
	            }
	        ]
		}
	};
	
	this.getStatusBar=function() {
		 return this.statusBar=new Ext.ux.StatusBar({
			 id: this.getId()+'-statusbar',
	         defaultText: 'Ready'
	     });
	};
	
	// TODO:
	this.getForm=function() {
		if (!this.form)
			this.form=this.items[0]
			
		return this.form;
	};
	
	// TODO:
	this.getGrid=function() {
		if (!this.grid)
			this.grid=this.items[1]
			
		return this.grid;
	};   
	
	this.obj={
		xtype	: 'panel',
		id      : this.container.name+'-panel-'+this.config.name,
		name	: this.config.name,
	    tbar	: this.getTbar(),	    
	    bbar	: this.getStatusBar(),
		items	: this.getItems(),
		layout  : 'absolute',
		border	: false		
	};
	
	this.get=function() {
		return this.obj;
	};
};	

JSER.ItemsNav={
	getApp: function(item) {
		getContainer=function (obj) {
			if (obj.constructor==JSER.App)
				return obj;				
			else if (obj.container)
				return getContainer(obj.container);			
		};
		
		return getContainer(item);	
	},
	getModule: function(item) {
		getContainer=function (obj) {
			if (obj.constructor==JSER.Module)
				return obj;				
			else if (obj.container)
				return getContainer(obj.container);			
		};
		
		return getContainer(item);
	},
	getRootPanel: function(item) {
		getContainer=function (obj) {
			if (obj.constructor==JSER.Panel)
				return obj;				
			else if (obj.container)
				return getContainer(obj.container);			
		};
		
		return getContainer(item);
	}	
};

JSER.ItemsParse=function(container, items) {
	
	var list=[];
	
	for (var i=0; i<items.length; i++) {
		
		var item=items[i];
		
		if (item.label) {
			var labelItem=new Object();
			labelItem.xtype='label';
			labelItem.name=item.name;
			labelItem.text=item.label;
			labelItem.x=item.x;
			labelItem.y=item.y;
			list.push(new JSER.FormItems.Label(container, labelItem));				
		}
		
		switch (item.xtype) {
		case 'window':
			list.push(new JSER.Window(container, item).get());
			break;
		case 'panel':
			list.push(new JSER.Panel(container, item).get());
			break;	
		case 'form':
			list.push(new JSER.Form(container, item));
			break;	
		case 'grid':
			list.push(new JSER.Grid(container, item));
			break;
		case 'textfield':
			list.push(new JSER.FormItems.TextField(container, item));
			break;	
		case 'combobox':
			list.push(new JSER.FormItems.ComboBox(container, item));
			break;
		case 'hidden':
			list.push(new JSER.FormItems.Hidden(container, item));
			break;	
		default:		
			list.push(item);
			break;
		}
	}
	
	return list;
};

JSER.WakeUp=function(item) {
	
	render=function(obj) {
		
		var newObj=obj.get();
		newObj.container=obj.container;
		
		if (obj.items)			
			for (var i=0; i<obj.items.length; i++)				
				newObj.items[i]=render(obj.items[i]);
		
		return newObj;			
	}
	
	return render(item);
};

JSER.FormItems={};

JSER.FormItems.TextField=function(container, config) {
	
	var scope=this;
	
	this.container=container;
	this.config=config;
	
	this.getY=function() {
		if (!this.y)
			this.y=(scope.config.label)? scope.config.y+15 : scope.config.y;
		
		return this.y;
	},	
	
	this.obj={
		xtype	: 'textfield',
		id		: container.name+'-textfield-'+config.name,
		name	: config.name,
		x		: config.x,
		y		: scope.getY(),
		width	: config.width
	}
	
	this.get=function() {
		return this.obj;
	};
};

JSER.FormItems.Hidden=function(container, config) {
	
	this.container=container;
	this.config=config;
	
	this.obj={
		xtype	: 'hidden',
		id      : container.name+'-hidden-'+config.name,
		name	: config.name
	}
	
	this.get=function() {
		return this.obj;
	};
};

JSER.FormItems.Label=function(container, config) {
	
	this.container=container;
	this.config=config;
	
	this.obj={
		xtype	: 'label',
		id		: this.container.name+'-label-'+this.config.name,
		text	: this.config.text+":",
		x		: this.config.x,
		y		: this.config.y,
	}
	
	this.get=function() {
		return this.obj;
	};
};

JSER.FormItems.ComboBox=function(container, config) {
	
	this.container=container;	
	this.config=config;	
	
	var that=this;
	
	this.getName=function() {
		this.name=this.config.name;			
		return this.name;	
	};
	
	this.getId=function() {
		if (!this.id) 
			this.id=(this.config.id)? this.config.id : this.id=this.container.name+'-combobox-'+this.config.name;
			
		return this.id;	
	};
	
	this.getStore=function() {
		if (!this.store)
			{
			var module=JSER.ItemsNav.getModule(this);
			var app=module.container;
			
			this.store=app.storage.create(app.storage.getRecord(this.config.entity), this);
			module.storeList.push(this.store);
			}
		
		return this.store;	
	};
	
	this.getValueField=function() {
		if (!this.valueField) 
			this.valueField=(this.config.valueField)? this.config.valueField : this.valueField='id';
			
		return this.valueField;	
	};

	this.getDisplayField=function() {
		if (!this.displayField) 
			this.displayField=(this.config.displayField)? this.config.displayField : this.displayField='name';
			
		return this.displayField;	
	};

	this.getMode=function() {
		if (!this.mode) 
			this.mode=(this.config.mode)? this.config.mode : this.mode='remote';
			
		return this.mode;	
	};
	
	this.getTypeAhead=function() {
		if (!this.typeAhead) 
			this.typeAhead=(this.config.typeAhead)? this.config.typeAhead : this.typeAhead='all';
			
		return this.typeAhead;	
	};
	
	this.getTriggerAction=function() {
		if (!this.triggerAction) 
			this.triggerAction=(this.config.triggerAction)? this.config.triggerAction : this.triggerAction='all';
			
		return this.triggerAction;	
	};
	
	this.getEmptyText=function() {
		if (!this.emptyText) 
			this.emptyText=(this.config.emptyText)? this.config.emptyText : this.emptyText='Selecione...';
			
		return this.emptyText;	
	};
	
	this.getSelectOnFocus=function() {
		if (!this.selectOnFocus) 
			this.selectOnFocus=(this.config.selectOnFocus)? this.config.selectOnFocus : this.selectOnFocus=true;
			
		return this.selectOnFocus;	
	};
	
	this.getWidth=function() {
		if (!this.width) 
			this.width=(this.config.width)? this.config.width : this.width=150;
			
		return this.width;	
	};
	
	this.getX=function() {		
		if (!this.x) 
			this.x=(this.config.x)? this.config.x : this.x=10;
			
		return this.x;			
	};
	
	this.getY=function() {
		if (!this.y)
			this.y=(this.config.label)? this.config.y+15 : this.config.y;
		
		return this.y;
	},	
	
	this.obj=new Ext.form.ComboBox({
		id				: that.getId(),
		name			: that.getName(),
        store			: that.getStore().get(),
        valueField		: that.getValueField(),
        displayField	: that.getDisplayField(),
        typeAhead		: that.getTypeAhead(),
        mode			: that.getMode(),
        triggerAction	: that.getTriggerAction(),
        emptyText		: that.getEmptyText(),
        selectOnFocus	: that.getSelectOnFocus(),
        width			: that.getWidth(),
        x				: that.getX(),
        y				: that.getY(),
    });	
	
	this.get=function() {
		return this.obj;
	};
};

JSER.Form=function(container, config) {
	
	var scope=this;
	
	this.container=container;
	this.config=config;	
	
	this.getName=function() {
		
		if (!this.name) {
			if (this.config.name)
				this.name=this.config.name;
			else if (this.container.name)
				this.name='form-'+this.container.name;
			else 
				this.name='form-'+Math.floor(Math.random());
		}
		
		return this.name;
	};
	
	this.getId=function() {
		if (!this.id)
			this.id=this.getName();
		
		return this.id;
	};	
	
	this.getItems=function() {
		if (!this.items)
			this.items=JSER.ItemsParse(this, this.config.items);
		
		return this.items;
	};
	
	this.getStore=function() {
		if (!this.store) 
			this.store=(this.config.store)? this.config.store : this.getAppModule();
		
		return this.store;
	};
	
	this.getAppModule=function() {
		var module=this.getModule();
		return module.store;
	};
	
	this.getModule=function() {
		getContainer=function (obj) {
			if (obj.xtype=='module')
				return obj;				
			else if (obj.container)
				return getContainer(obj.container);			
		};
		
		return getContainer(this);
	};
	
	this.getLinkedItem=function() {
		if (!this.linkedItem)
			this.linkedItem=(this.config.linkedItem)? this.config.linkedItem : null;
			
		return this.linkedItem
	};
	
	this.obj={
		xtype		: 'form',	
		id			: this.getId(),
		name		: this.getName(),
	    frame		: false,
	    border		: false,
	    labelAlign	: 'left',
	    bodyStyle	: 'padding:5px',
	    defaultType	: 'textfield',
	    layout  	: 'absolute',
	    height		: 200,
	    
	    store: this.getStore().get(),    
	    
	    bindRecord: function(obj) {	    	 
	    	for (var i=0; i<scope.config.items.length; i++) 
	    		obj.set(scope.config.items[i].name, scope.get().getForm().findField(scope.config.items[i].name).getValue());
			
			return obj; 
	    },
	    
	    saveRecord: function() {
	    	var rec=this.grid.selModel.getSelected();
	    	
	    	if (rec)
	    		this.editRecord(this.bindRecord(rec));
	    	else
	    		this.createRecord(this.bindRecord(new scope.config.record));
	    },
	    
	    createRecord: function(rec) {
	    	
	    	var scopeForm=this;
	    	
			if (this.getForm().isValid()) {
				
				this.state.create.runing();
				
				Ext.Ajax.request({
					url: scope.getStore().proxy.url,
					method: "POST",
					params: '{"data": '+Ext.encode(rec.data)+'}',
					headers: {
						'Content-Type': 'application/json; charset=UTF-8'
					},
					success: function(response, request) {
						var resp=Ext.decode(response.responseText);
						
						if (resp.success)
							scope.get().state.create.success(resp.message);
						else
							scope.get().state.create.failure(resp.message);
					}
				});                  			
			} 
			else
				scope.get().state.create.failure("Registro não é válido para ser inserido!");
	    },
	    
	    editRecord: function(rec) {
			try
			{
				if (!rec.modified)
					throw("Nenhuma informação alterada no registro.");
				
				if (!this.getForm().isValid())
					throw("Registro não é válido para ser atualizado!");
				
				this.state.update.runing();
				
				Ext.Ajax.request({
					url: scope.getStore().proxy.url+"/"+rec.data.id,
					method: "PUT",
					params: '{"data": '+Ext.encode(rec.data)+'}',
					headers: {
						'Content-Type': 'application/json; charset=UTF-8'
					},
					success: function(response, request) {
						var resp=Ext.decode(response.responseText);
						
						if (resp.success)
							scope.get().state.update.success(resp.message);
						else {
							scope.get().grid.selModel.getSelected().cancelEdit();
							scope.get().state.update.failure(resp.message);
						}
					}
				});
			}
			catch (e)
			{
				scope.get().state.update.failure(e);
			}				
	    },
	    
	    deleteRecord: function() {
	    	var id=Ext.getCmp(scope.getName()+"-hidden-id").getValue();
	    	
	    	this.container.state().destroy().runing();
	    	
	    	Ext.Ajax.request({
				url: this.store.proxy.url+"/"+id,
				method: "DELETE",
				success: function(response, request) {
					var resp=Ext.decode(response.responseText);
					
					if (resp.success)
						scope.get().state.destroy.success(resp.message);
					else
						scope.get().state.destroy.failure(resp.message);
				}
			});
	    },
	    
	    items: this.getItems()
	};
	
	this.get=function() {
		return this.obj;
	}
};

JSER.Grid=function(container, config) {
	
	var that=this;
	
	this.container=container;
	this.config=config;
	
	this.getName=function() {
		if (!this.name)
			this.name=(this.config.name)? this.config.name : this.container.name+'-grid';
		
		return this.name;
	};
	
	this.getId=function() {
		return this.getName();
	};
	
	this.getTitle=function() {
		return (this.config.title)? this.config.title : 'Lista de '+this.getName();
	};
	
	this.getStore=function() {
		if (!this.store)
			this.store=(this.config.store)? this.config.store : this.getModule().store;		
		
		return this.store;
	};
	
	this.getModule=function() {
		getContainer=function (obj) {
			if (obj.xtype=='module')
				return obj;				
			else if (obj.container)
				return getContainer(obj.container);			
		};
		
		return getContainer(this);
	};
	
	this.getX=function() {
		return (this.config.x)? this.config.x : 5;
	};
	
	this.getY=function() {
		if (this.config.y==undefined)
			throw ("Defina a posição y da grid "+this.config.name+".");
		
		return this.config.y;
	};

	this.getWidth=function() {
		return (this.config.width)? this.config.width : 576;
	};

	this.getHeight=function() {
		return (this.config.height)? this.config.height : 393;
	};	
	
	this.getBbar=function() {
		return new Ext.PagingToolbar({
		       pageSize		: PAGE_LIMIT,
		       store		: that.store,
		       displayInfo	: true,
		       displayMsg	: 'Exibindo registros {0} - {1} of {2}',
		       emptyMsg		: "Nenhum registro encontrado."
		});
	};
	
	this.getColModel=function() {
		return new Ext.grid.ColumnModel({
			defaults: {
				xtype		: 'gridcolumn',
	            width		: 120,
	            sortable	: true
	        },
	        columns: this.config.columns	
		});		
	};
	
	this.getSelModel=function() {
		return new Ext.grid.RowSelectionModel({
			singleSelect: true,
			listeners: {
				rowselect: function(sm, row, rec) {
					var rootPanel=JSER.ItemsNav.getRootPanel(that);
					rootPanel.state().update().ready(rec);
				}
			}
		});
	};	
	
	this.obj={	
		xtype		: 'grid',	
		title		: this.getTitle(),
	    id			: this.getId(),
	    x			: this.getX(),
	    y			: this.getY(),
	    width		: this.getWidth(),
	    height		: this.getHeight(),
	    border		: true,
	    store		: this.getStore().get(),
	    colModel	: this.getColModel(),
	    selModel	: this.getSelModel(),
	    bbar		: this.getBbar()		
	};
	
	this.get=function() {
		return this.obj;
	};
};

JSER.Column=function(config) {
	
	this.config=config;
	
	this.getXtype=function() {
		return this.xtype=(this.config.xtype)? this.config.xtype : 'gridcolumn';
	};
	
	this.getSortable=function() {
		return this.sortable=(this.config.sortable)? this.config.sortable : true;
	};

	this.getWidth=function() {
		return this.width=(this.config.width)? this.config.width : 100;
	};

	this.getDataIndex=function() {
		if (this.config.dataIndex==undefined)
			throw ("Defina a propriedade dataIndex da grid.");
		
		return this.config.dataIndex; 
	};

	this.getHeader=function() {
		if (this.config.header==undefined)
			throw ("Defina a propriedade header da grid.");
		
		return this.config.header; 
	};

	this.objColumn=new Ext.grid.Column({
		xtype: this.getXtype(),
        dataIndex: this.getDataIndex(),
        header: this.getHeader(),
        sortable: this.getSortable(),
        width: this.getWidth()
	});
};

function merge (o1, o2) 
	{
	for (var z in o2) {
		if (o2.hasOwnProperty(z)) {
			o1[z] = o2[z];
		}
	}
	return o1;
};

JSER.Controller=function(module) {
	
	this.module=module;
	
	this.state=function() {
    	this.create=function() {    		
    		this.ready=function() {    	
    	    	Ext.getCmp(that.getId()+'-button-new').disable();
    	    	Ext.getCmp(that.getId()+'-button-delete').disable();
    	    	
    	    	that.statusBar.setIcon('');
    	    	that.statusBar.setText('Pronto.');
    	    	
    	    	Ext.getCmp(that.getGrid().id).selModel.clearSelections();
    	    	Ext.getCmp(that.getForm().id).getForm().reset();
    	    };
    	    
    	    this.runing=function(msg) {  
    	    	that.get().__running(msg || 'Inserindo registro...');
    	    };
    	    
    	    this.success=function(msg, id) {  
    	    	that.get().__success(msg || 'Registro inserido com sucesso!');
    	    };
    	    
    	    this.failure=function(msg) {
    	    	that.get().__failure(msg || 'Falha ao inserir registro!');
    	    };	
    	    
    	    return this;
    	};
    	
    	this.update=function() {
    		
    		this.ready=function(obj) {
    	    	Ext.getCmp(that.getId()+'-button-new').enable();
    	    	Ext.getCmp(that.getId()+'-button-delete').enable();
    	    	
    	    	if (typeof obj=='object') {
    	    		Ext.getCmp(that.getForm().id).getForm().loadRecord(obj);
    	    	}	
    	        else {
    				Ext.getCmp(form.getId()+'-hidden-id').setValue(obj);
    				that.getGrid().selModel.clearSelections();
    				that.getStore().reload();
    	        }        	
    	    };
    	    
    	    this.runing=function(msg) {  
    	    	that.get().__running(msg || 'Atualizando registro...');
    	    };
    	    
    	    this.success=function(msg) {  
    	    	that.get().__success(msg || 'Registro atualizado com sucesso!');
    	    };
    	    
    	    this.failure=function(msg) {
    	    	that.get().__failure(msg || 'Falha ao atualizar registro!');
    	    };
    	    
    	    return this;
    	};
    	
    	this.destroy=function() {	
    		
    		this.runing=function(msg) {  
    	    	that.__running(msg || 'Deletando registro...');
    	    };
    	    
    	    this.success=function(msg) { 
    	    	that.state().create().ready();
    	    	that.get().__success(msg || 'Registro deletado com sucesso!');
    	    };
    	    
    	    this.failure=function(msg) {
    	    	that.get().__failure(msg || 'Falha ao deletar registro!');
    	    };
    	    
    	    return this;
    	};
    	
    	return this;
    };
    
    this.__running=function(msg) {  
    	that.__showMask();
    	that.statusBar.setIcon('x-status-busy');
    	that.statusBar.setText(msg);
    };
    
    this.__success=function(msg) {  
    	that.__hideMask();
    	that.statusBar.setIcon('x-status-valid');
    	that.statusBar.setText(msg);
    	that.getStore().reload();
    };
    
    this.__failure=function(msg) {
    	that.__hideMask();
    	that.statusBar.setIcon('x-status-error');
    	that.statusBar.setText(msg);
    	that.getStore().reload();
    };
    
    this.__showMask=function() {
    	Ext.getCmp(that.getId()).getForm().getEl().mask();
    };	    
    
    this.__hideMask=function() {
    	Ext.getCmp(that.getId()).getForm().getEl().unmask();
    };	
	
};

JSER.Module=function(container, config) {
	
	var scope=this;
		
	this.container=container;
	this.config=config;
	
	this.xtype='module';
	this.id='module-'+this.config.name;
	this.name=this.config.name;
	this.title=this.config.title;
	this.controller=this.config.controller;
	this.record=this.container.storage.getRecord(config.entity);
	this.store=this.container.storage.getStore(config.entity);
	
	this.storeList=[this.store];
	
	this.panel=new JSER.Panel(this, {items: this.config.items})
		
	this.items=[ this.panel ];
};

JSER.App=function(type) {
	
	this.type=type;
	
	this.moduleList=[];
	this.storage=new JSER.Storage();
	this.controller=new JSER.Controller();
	
	var scope=this;
	
	this.getUiManager=function() {
		var ui;
		
		switch(this.type) {
			case 'desktop': 
				ui=new JSER.UI.Desktop();
			  break;
		};
		
		return ui;
	};
	
	this.uiManager=this.getUiManager();
	
	this.add=function(config) {		
		this.moduleList.push(new JSER.Module(this, config));		
	};
	
	this.get=function(name) {
		for (var i=0; i<this.moduleList.length; i++)
			if (this.moduleList[i].name=name)
				return this.moduleList[i].name;
		
		return null;
	};
	
	this.run=function() {
		for (var i=0; i<this.moduleList.length; i++)
			this.uiManager.add(this.moduleList[i]);	
		
		Ext.QuickTips.init();
	};
};

JSER.UI={};

JSER.UI.Desktop=function() {
	
	this.moduleList=[];
	var scope=this;
	
	this.desktop=new Ext.app.App({
		getModules : function(){
			return scope.moduleList;
		},
	    getStartConfig : function(){
	        return {
	            title: logged.User.name,
	            iconCls: 'user',
	            toolItems: [{
	                text:'Config.',
	                iconCls:'settings',
	                scope:this
	            },'-',{
	                text:'Logout',
	                iconCls:'logout',
	                scope:this,
	                handler: function () {
	                	window.location='login';
	                }
	            }]
	        };
	    }
	});
	
	this.add=function(config) {		 
		var modulePrototype=Ext.extend(Ext.app.Module, new JSER.UI.Desktop.Module(this, config).get());
		var newModule=new modulePrototype();
		newModule.storeList=config.storeList;
		this.moduleList.push(newModule);
	};
	
	this.get=function() {
		return this.desktop;
	};
};

JSER.UI.Desktop.Window=function(container, config) {
	
	var scope=this;
	
	this.container=container;
	this.config=config;
	
	this.items=null;
	
	this.getId=function() {
		this.id=this.config.name+'-win';
		return this.id;
	};
	
	this.getTitle=function() {
		this.title=this.config.title;
		return this.title;
	};
	
	this.getItems=function() {		
		this.items=this.container.config.items;
		return this.items;
	};
	
	this.getWidth=function() {
		this.width=(this.config.width)? this.config.width : 600;
		return this.width;
	};
	
	this.getHeight=function() {
		this.heigth=(this.config.height)? this.config.height : 600;
		return this.heigth; 
	};
	
	this.obj={            		
    	id: this.getId(),
        title: this.getTitle(),
        width: this.getWidth(),
        height: this.getHeight(),
        iconCls: 'icon-grid',
        shim: false,
        animCollapse: false,
        constrainHeader: true,
        resizable: true,
        closeAction: 'close',
        layout: 'fit',
        items: this.getItems()
    };
	
	this.get=function() {
		return this.obj;
	};	
};

JSER.UI.Desktop.Module=function(container, config) {
	
	var scope=this;
	
	this.container=container;
	this.config=config;
	
	this.getId=function() {
		return 'desktop-module-name-TODO';
	};
	
	this.getTitle=function() {
		return this.config.title;
	};
	
	this.window=JSER.WakeUp(new JSER.UI.Desktop.Window(this, merge(this.config.config.window, { title: this.config.config.title })));
	
	this.loadStores=function() {
		for (var i=0; i<this.config.storeList.length; i++) 
			this.config.storeList[i].get().reload();
	};

	this.module={
	    id: this.getId(),
	    init : function() {
	        this.launcher = {
	            text: scope.getTitle(),
	            iconCls:'icon-grid',
	            handler : this.createWindow,
	            scope: this
	        }
	    },
	    createWindow : function() {
	        var desktop = this.app.getDesktop();
	        var win = desktop.getWindow(scope.getId());
	        
	        if(!win){
	            win = desktop.createWindow(scope.window); 	            
	            win.on({
	                'activate': {
	                	fn: function() {
	                    	scope.loadStores();	            			
	                    }
	                },
	                'close': {
	                	fn: function() {
	                		;
	                	}	
	                }});
	        }   
	        win.show();
	    }
	};
	
	this.get=function() {
		return this.module;
	};
};

JSER.Storage=function() {
	
	this.storeList=[];
	this.recordList=[];
	
	this.add=function(config) {		
		record=new JSER.Record(config);
		
		this.recordList.push(record);
		
		var store=new JSER.Store({
			name: config.name,
			controller: config.controller,
			entity: record,
			readerFields: record.fields
		});
		
		this.storeList.push(store);
	};
	
	this.create=function(record, component) {
		var store=new JSER.Store({
			name: 'store-'+component.container.name+'-'+component.name,
			controller: record.controller,
			entity: record,
			readerFields: record.fields
		});
		
		this.storeList.push(store);
		return store;
	};
	
	this.getRecord=function(name) {
		for (var i=0; i<this.recordList.length; i++)
			if (this.recordList[i].name==name)
				return this.recordList[i];
		
		return null;
	};
	
	this.getStore=function(name) {
		for (var i=0; i<this.storeList.length; i++)
			if (this.storeList[i].name==name)
				return this.storeList[i];
		
		return null;
	};
};